import * as _ from "lodash"
import { camelCase } from "../case"
import { PageList } from "../data"
import httpClient from "../httpclient"

export enum OrderDisputeKind {
  OnlyRefund = "only_refund",
  ReturnRefund = "return_refund"
}

export enum OrderDisputeStatus {
  Incomplete = "incomplete",
  Applying = "applying",
  Reapplying = "reapplying",
  Cancelled = "cancelled",
  Disapproved = "disapproved",
  Pending = "pending",
  Succeeded = "succeeded",
  Failed = "failed"
}

export enum OrderDisputeItemStatus {
  NotReceived = "not_received", Received = "received"
}

export class OrderDisputeTransaction {
  public id: string
  public storeId: string
  public orderId: string
  public kind: OrderDisputeKind
  public itemStatus: OrderDisputeItemStatus

  public itemId: string
  public name: string
  public itemAmount: number
  public itemShipped: number
  public amount: number
  public imageUrl: string
  public notes: string
  public attachments: string[]

  public status: OrderDisputeStatus
  public reason: string
  public disapprovalReason: string
  public failReason: string
  public appliedTime: string
  public approvedTime: string
  public disapprovedTime: string
  public succeededTime: string
  public createdTime: string
}

export class OrderDispute {
  public static ItemStatus = OrderDisputeItemStatus

  public id: string
  public storeId: string
  public storeName: string
  public orderId: string
  public kind: OrderDisputeKind
  public itemStatus: OrderDisputeItemStatus
  public applicant: string
  public applicantId: string
  public transactions: OrderDisputeTransaction[] = []

  public itemId: string
  public name: string
  public itemAmount: number
  public itemShipped: number
  public amount: number
  public imageUrl: string
  public notes: string
  public attachments: string[]

  public status: OrderDisputeStatus
  public applyingExpires: number
  public applyingExpiredTime: string
  public reason: string
  public disapprovalReason: string
  public failReason: string
  public appliedTime: string
  public approvedTime: string
  public disapprovedTime: string
  public succeededTime: string
}

export function assignOrderDispute(refund: OrderDispute) {
  return _.assign(new OrderDispute(), refund)
}

export class OrderDisputeQuery {

  private params = {}

  public page(page?: string | number): OrderDisputeQuery {
    if (page) {
      this.params["page"] = page
    }
    return this
  }

  public limit(limit?: string | number): OrderDisputeQuery {
    if (limit) {
      this.params["limit"] = limit
    }
    return this
  }

  public storeId(storeId: string): OrderDisputeQuery {
    this.params["store_id"] = storeId
    return this
  }

  public customerId(customerId: string): OrderDisputeQuery {
    this.params["customer_id"] = customerId
    return this
  }

  public orderId(orderId: string): OrderDisputeQuery {
    this.params["order_id"] = orderId
    return this
  }

  public ids(ids: string[] | string): OrderDisputeQuery {
    this.params["ids"] = ids
    return this
  }

  public kinds(kinds?: OrderDisputeKind[] | string): OrderDisputeQuery {
    if (kinds) {
      this.params["kinds"] = kinds
    }
    return this
  }

  public statuses(statuses?: OrderDisputeStatus[] | string): OrderDisputeQuery {
    if (statuses) {
      this.params["statuses"] = statuses
    }
    return this
  }

  public sort(sort: string): OrderDisputeQuery {
    if (sort) {
      this.params["sort"] = sort
    }
    return this
  }

  public list(): Promise<PageList<OrderDispute>> {
    return httpClient.get("/v1/orders/disputes", {
      params: this.params,
    }).then(({ data }) => data)
      .then(camelCase)
      .then(data => {
        return _.assign(new PageList<OrderDispute>(), data, {
          elements: _.map(data.elements, assignOrderDispute),
        })
      })
  }

  public count(): Promise<number> {
    return httpClient.get("/v1/orders/disputes/count", {
      params: this.params,
    }).then(({ data }) => data)

  }
}

export class OrderDisputeServiceV1 {
  public static createOrderDisputeQuery() {
    return new OrderDisputeQuery()
  }
}
